package com.library.controller;

import com.library.dto.BookDTO;
import com.library.dto.BorrowRecordDTO;
import com.library.dto.UserDTO;
import com.library.exception.ForbiddenException;
import com.library.repository.BookRepository;
import com.library.repository.BorrowRecordRepository;
import com.library.repository.UserRepository;
import com.library.service.BookService;
import com.library.service.BorrowService;
import com.library.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 报表导出控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/reports")
@RequiredArgsConstructor
public class ReportController {
    private final BookService bookService;
    private final BorrowService borrowService;
    private final UserService userService;

    /**
     * 导出图书列表（CSV格式）
     * GET /api/reports/books
     */
    @GetMapping("/books")
    public ResponseEntity<byte[]> exportBooks(@RequestAttribute String role) {
        // 检查管理员权限
        if (!"admin".equals(role)) {
            throw new ForbiddenException("需要管理员权限");
        }

        // 获取所有图书
        List<BookDTO> books = bookService.searchBooks(null, null, null);

        // 生成CSV内容
        StringBuilder csv = new StringBuilder();
        csv.append("ID,书名,作者,ISBN,分类,描述,库存,是否推荐,创建时间\n");
        for (BookDTO book : books) {
            csv.append(book.getId()).append(",")
               .append(escapeCsv(book.getTitle())).append(",")
               .append(escapeCsv(book.getAuthor())).append(",")
               .append(escapeCsv(book.getIsbn())).append(",")
               .append(escapeCsv(book.getCategory())).append(",")
               .append(escapeCsv(book.getDescription())).append(",")
               .append(book.getStock()).append(",")
               .append(book.getIsRecommended() ? "是" : "否").append(",")
               .append(book.getCreatedAt()).append("\n");
        }

        byte[] bytes = csv.toString().getBytes(StandardCharsets.UTF_8);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "books.csv");
        headers.setContentLength(bytes.length);

        //导出文件到报表文件夹中
        String fileName = "books_" + System.currentTimeMillis() + ".csv";
        try (PrintWriter writer = new PrintWriter(fileName, StandardCharsets.UTF_8)) {
            writer.write(csv.toString());
        } catch (Exception e) {
            log.error("导出图书列表到文件失败", e);
            throw new RuntimeException("导出图书列表到文件失败", e);
        }

        // 返回CSV文件
        log.info("导出图书列表成功");

        return ResponseEntity.ok()
                .headers(headers)
                .body(bytes);
    }

    /**
     * 导出借阅记录（CSV格式）
     * GET /api/reports/borrow
     */
    @GetMapping("/borrow")
    public ResponseEntity<byte[]> exportBorrowRecords(
            @RequestAttribute Long userId,
            @RequestAttribute String role) {
        // 检查管理员权限
        if (!"admin".equals(role)) {
            throw new ForbiddenException("需要管理员权限");
        }

        // 获取所有借阅记录
        List<BorrowRecordDTO> records = borrowService.getBorrowRecords(userId, true, null);

        // 生成CSV内容
        StringBuilder csv = new StringBuilder();
        csv.append("ID,用户ID,用户名,图书ID,书名,作者,ISBN,分类,借阅日期,归还日期,状态\n");
        for (BorrowRecordDTO record : records) {
            csv.append(record.getId()).append(",")
               .append(record.getUserId()).append(",")
               .append(escapeCsv(record.getUsername())).append(",")
               .append(record.getBookId()).append(",")
               .append(escapeCsv(record.getTitle())).append(",")
               .append(escapeCsv(record.getAuthor())).append(",")
               .append(escapeCsv(record.getIsbn())).append(",")
               .append(escapeCsv(record.getCategory())).append(",")
               .append(record.getBorrowDate()).append(",")
               .append(record.getReturnDate() != null ? record.getReturnDate().toString() : "").append(",")
               .append(record.getStatus()).append("\n");
        }

        byte[] bytes = csv.toString().getBytes(StandardCharsets.UTF_8);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "borrow_records.csv");
        headers.setContentLength(bytes.length);

        //导出文件到报表文件夹中
        String fileName = "borrow_records_" + System.currentTimeMillis() + ".csv";
        try (PrintWriter writer = new PrintWriter(fileName, StandardCharsets.UTF_8)) {
            writer.write(csv.toString());
        } catch (Exception e) {
            log.error("导出借阅记录到文件失败", e);
            throw new RuntimeException("导出借阅记录到文件失败", e);
        }

        // 返回CSV文件
        log.info("导出借阅记录成功");

        return ResponseEntity.ok()
                .headers(headers)
                .body(bytes);
    }

    /**
     * 导出用户列表（CSV格式）
     * GET /api/reports/users
     */
    @GetMapping("/users")
    public ResponseEntity<byte[]> exportUsers(@RequestAttribute String role) {
        // 检查管理员权限
        if (!"admin".equals(role)) {
            throw new ForbiddenException("需要管理员权限");
        }

        // 获取所有用户
        com.library.dto.PageResponse<UserDTO> pageResponse = userService.getUserList(null, null, null, 1, 10000, "createdAt", "desc");
        List<UserDTO> users = pageResponse.getContent();

        // 生成CSV内容
        StringBuilder csv = new StringBuilder();
        csv.append("ID,用户名,角色,邮箱,电话,状态,创建时间\n");
        for (UserDTO user : users) {
            csv.append(user.getId()).append(",")
               .append(escapeCsv(user.getUsername())).append(",")
               .append(escapeCsv(user.getRole())).append(",")
               .append(escapeCsv(user.getEmail())).append(",")
               .append(escapeCsv(user.getPhone())).append(",")
               .append(escapeCsv(user.getStatus())).append(",")
               .append(user.getCreatedAt()).append("\n");
        }

        byte[] bytes = csv.toString().getBytes(StandardCharsets.UTF_8);
        
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", "users.csv");
        headers.setContentLength(bytes.length);

        //导出文件到报表文件夹中
        String fileName = "users_" + System.currentTimeMillis() + ".csv";
        try (PrintWriter writer = new PrintWriter(fileName, StandardCharsets.UTF_8)) {
            writer.write(csv.toString());
        } catch (Exception e) {
            log.error("导出用户列表到文件失败", e);
            throw new RuntimeException("导出用户列表到文件失败", e);
        }

        // 返回CSV文件
        log.info("导出用户列表成功");

        return ResponseEntity.ok()
                .headers(headers)
                .body(bytes);
    }

    /**
     * 转义CSV字段中的特殊字符
     */
    private String escapeCsv(String value) {
        if (value == null) {
            return "";
        }
        // 如果包含逗号、引号或换行符，需要用引号包裹，并转义引号
        if (value.contains(",") || value.contains("\"") || value.contains("\n")) {
            return "\"" + value.replace("\"", "\"\"") + "\"";
        }
        return value;
    }
}

